package com.usian.comment.service.impl;

import com.usian.comment.entity.ApComment;
import com.usian.comment.entity.ApCommentLike;
import com.usian.comment.service.CommentService;
import com.usian.comment.vo.CommentVo;
import com.usian.common.aliyun.GreenTextScan;
import com.usian.common.enums.AppHttpCodeEnum;
import com.usian.common.exception.LeadException;
import com.usian.common.threadlocal.UserThreadLocalUtils;
import com.usian.common.util.BeanHelper;
import com.usian.model.comment.dtos.CommentDto;
import com.usian.model.comment.dtos.CommentLikeDto;
import com.usian.model.comment.dtos.CommentSaveDto;
import com.usian.model.user.dtos.UserInfoDto;
import com.usian.user.client.UserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private GreenTextScan greenTextScan;

//    发表评论
    @Override
    public void saveComment(CommentSaveDto dto) {
//        参数校验
        if (dto==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
//        从线程中获取用户id，判断用户登录状态
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId==null){
            throw new LeadException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //文本审核
//        try {
//            Map<String, String> map = greenTextScan.greenTextScan(dto.getContent());
//            if (!map.get("suggestion").equals("pass")){
//                throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"评论违规");
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new LeadException(AppHttpCodeEnum.SERVER_ERROR,"调用阿里云文本反垃圾文本失败");
//        }

        //查询发表评论的用户信息
        UserInfoDto userInfoDto = userFeign.findById(userId);
//        组装评论的数据，保存到mongodb中
        ApComment apComment = new ApComment();
        apComment.setAuthorId(userId);
        apComment.setAuthorName(userInfoDto.getName());
        apComment.setContent(dto.getContent());
        apComment.setEntryId(dto.getArticleId());
        apComment.setCreatedTime(new Date());
        apComment.setUpdatedTime(new Date());
        apComment.setImage(userInfoDto.getImage());
        apComment.setLikes(0);
        apComment.setReply(0);
        apComment.setType(0);
        apComment.setFlag(0);
        mongoTemplate.insert(apComment);
    }

//    查询评论列表
    @Override
    public List<CommentVo> loadComment(CommentDto dto) {
//        参数校验
        if (dto==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
//        条件查询评论列表
        //根据文章id查询
        Query query = new Query();
        query.addCriteria(Criteria.where("entryId").is(dto.getArticleId()));
        if(dto.getMinLikes() != null && dto.getMinLikes()>0){
//            小于最小点赞数
            query.addCriteria(Criteria.where("likes").lt(dto.getMinLikes()));
        }
        //根据点赞排序
        query.with(Sort.by(Sort.Direction.DESC,"likes"));
        //设置分页条件
        Pageable pageable = PageRequest.of(dto.getPage().intValue()-1,dto.getSize().intValue());
        query.with(pageable);
        //执行查询
        List<ApComment> commentList = mongoTemplate.find(query, ApComment.class);
        if (CollectionUtils.isEmpty(commentList)){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //数据转换
        List<CommentVo> commentVoList = BeanHelper.copyWithCollection(commentList, CommentVo.class);
//        获取用户id，判断用户是否登录
        Integer userId = UserThreadLocalUtils.getUserId();
        if (userId==null){
            //未登录，直接返回评论列表
            return commentVoList;
        }
//        如果用户登录了，需要查询登录用户是否对评论进行点赞
        //获取所有评论id
        List<String> commentIds = commentVoList.stream().map(CommentVo::getId).collect(Collectors.toList());
        //查询用户是否给某个评论点赞
        Query query2 = new Query();
        query2.addCriteria(Criteria.where("authorId").is(userId)
                                                     .and("commentId")
                                                     .in(commentIds)
                                                     .and("operation")
                                                     .is(0));
        List<ApCommentLike> commentLikes = mongoTemplate.find(query2, ApCommentLike.class);
        //获取点赞列表中的评论id
        if (!CollectionUtils.isEmpty(commentLikes)){
            List<String> likeCommentIds = commentLikes.stream().map(ApCommentLike::getCommentId).collect(Collectors.toList());
            //为点赞过的评论数据，属性赋值0
            commentVoList.stream().forEach(commentVo -> {
                //判断点赞的评论中遍历的commentvo的id值
                if (likeCommentIds.contains(commentVo.getId())){
                    commentVo.setOperation(0);
                }
            });

        }
        return commentVoList;
    }

//    点赞评论
    @Override
    public void likeComment(CommentLikeDto dto) {
//        参数校验
        if (dto==null){
            throw new LeadException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
//        获取用户id，如果没有登录，提示先进行等录
        Integer userId = UserThreadLocalUtils.getUserId();
        //评论id
        String commentId = dto.getCommentId();
//        根据评论id查询
        ApComment apComment = mongoTemplate.findById(commentId, ApComment.class);
        if (userId==null){
            throw new LeadException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
//        查询用户是否对当前评论点赞过。一个用户对同一个评论，只能点赞一次
        Query query = new Query();
        query.addCriteria(Criteria.where("commentId")
                                  .is(commentId))
                                  .addCriteria(Criteria.where("authorId")
                                  .is(userId));
        ApCommentLike commentLike = mongoTemplate.findOne(query, ApCommentLike.class);
//        如果是没有查到点赞记录，并且用户是点赞行为，需要更新点赞次数+1，并且记录点赞行为
        if (commentLike==null && dto.getOperation()==0){
            //新增评论点赞
            commentLike = new ApCommentLike();
            commentLike.setAuthorId(userId);
            commentLike.setCommentId(commentId);
            commentLike.setOperation(dto.getOperation());
            mongoTemplate.save(commentLike);
            //更新点赞评论数
            Query query1 = new Query(Criteria.where("_id").is(commentId));
            Update update = new Update();
            update.inc("likes");
            mongoTemplate.updateFirst(query1,update,ApComment.class);
        }else if (commentLike!=null && dto.getOperation()!=commentLike.getOperation()){
            //更新ApCommentLike的Operation
            commentLike.setOperation(dto.getOperation());
            mongoTemplate.save(commentLike);
            //如果点赞数量已经是0，即便是取消点赞也不能再减一
            int opt = dto.getOperation()==0?1:-1;
            if (opt==-1 && apComment.getLikes()<1){
                return;
            }
//        如果查询到点赞记录，更新点赞状态以及点赞次数
            Query query1 = new Query(Criteria.where("_id").is(commentId));
            Update update = new Update();
            update.inc("likes",opt);
            mongoTemplate.updateFirst(query1,update,ApComment.class);
        }
    }
}
